package com.zjt.smart.util;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.os.Looper;
import android.text.TextUtils;
import android.widget.ImageView;

import com.bumptech.glide.BitmapRequestBuilder;
import com.bumptech.glide.DrawableRequestBuilder;
import com.bumptech.glide.GifRequestBuilder;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.load.Transformation;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.target.Target;
import com.zjt.smart.R;
import com.zjt.smart.app.Config;
import com.zjt.smart.app.MainApplication;
import com.zjt.smart.ui.base.BaseActivity;
import com.zjt.smart.util.transformation.BlurTransformation;
import com.zjt.smart.util.transformation.CircleTransformation;
import com.zjt.smart.util.transformation.RoundedCornersTransformation;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.concurrent.ExecutionException;

public class ImageUtil {

    private final static int DEFAULT_RES = R.drawable.bg_image_default;
    private final static int DEFAULT_ROUND_RES = R.mipmap.ic_launcher_round;
    private final static int DEFAULT_CORNER_RADIUS = 30;

    public static void load(Context context, ImageView view, String url) {
        load(context, view, url, DEFAULT_RES);
    }

    public static void load(Context context, ImageView view, String url, int defRes) {
        load(context, view, url, defRes, null);
    }

    public static void loadRounCorner(Context context, ImageView view, String url) {
        loadRounCorner(context, view, url, DEFAULT_ROUND_RES);
    }

    public static void loadRounCorner(Context context, ImageView view, String url, int defRes) {
        Transformation transformation = new RoundedCornersTransformation(view.getContext(), DEFAULT_CORNER_RADIUS, 0);
        load(context, view, url, defRes, transformation);
    }

    public static void loadRounCorner(Context context, ImageView view, String url, int defRadius, int defRes) {
        Transformation transformation = new RoundedCornersTransformation(view.getContext(), defRadius, 0);
        load(context, view, url, defRes, transformation);
    }

    public static void loadBlur(Context context, ImageView view, String url) {
        loadBlur(context, view, url, DEFAULT_RES);
    }

    public static void loadBlur(Context context, ImageView view, String url, int defRes) {
        Transformation transformation = new BlurTransformation(view.getContext());
        load(context, view, url, defRes, transformation);
    }

    public static void loadCircle(Context context, ImageView view, String url) {
        CircleTransformation circleTransformation = new CircleTransformation(view.getContext());
        load(context, view, url, DEFAULT_ROUND_RES, circleTransformation);
    }

    public static void loadCircle(Context context, ImageView view, String url, int defRes) {
        CircleTransformation circleTransformation = new CircleTransformation(view.getContext());
        load(context, view, url, defRes, circleTransformation);
    }

    public static void load(Context context, ImageView view, String url, int defRes, Transformation transformation) {
        if(view == null){
            return;
        }
        if (TextUtils.isEmpty(url)){
            view.setImageResource(defRes);
            Glide.clear(view);
            return;
        }
        if (url.toLowerCase().contains(".gif")) {
            loadGif(context, view, url,defRes);
            return;
        }

        RequestManager manager = getRequestManager(context);
        DrawableRequestBuilder builder = manager
                .load(url)
                .placeholder(defRes)
                .error(defRes)
                .diskCacheStrategy(DiskCacheStrategy.SOURCE)
                .dontAnimate()
                .crossFade();
        if (transformation != null) {
            builder.bitmapTransform(transformation);
        }
        builder.into(view);
    }

    public static void loadCircleNoCache(Context context, ImageView view, String url) {
        int defRes = DEFAULT_ROUND_RES;
        CircleTransformation circleTransformation = new CircleTransformation(view.getContext());
        if(view == null){
            return;
        }
        if (TextUtils.isEmpty(url)){
            view.setImageResource(defRes);
            Glide.clear(view);
            return;
        }

        RequestManager manager = getRequestManager(context);
        DrawableRequestBuilder builder = manager
                .load(url)
                .placeholder(defRes)
                .error(defRes)
                .skipMemoryCache(true)
                .diskCacheStrategy(DiskCacheStrategy.NONE)
                .dontAnimate()
                .crossFade()
                .bitmapTransform(circleTransformation);
        builder.into(view);
    }

    public static void loadFile(Context context, ImageView view, File file) {
        if(view == null || file==null){
            return;
        }
        RequestManager manager = getRequestManager(context);
        DrawableRequestBuilder builder = manager
                .load(file)
                .diskCacheStrategy(DiskCacheStrategy.NONE)
                .dontAnimate()
                .crossFade();
        builder.into(view);
    }

    public static void loadGif(Context context, ImageView view, String url, int defRes) {
        loadGif(context,view,url,defRes,Target.SIZE_ORIGINAL,Target.SIZE_ORIGINAL, null);
    }

    public static void loadRoundGif(Context context, ImageView view, String url) {
        Transformation transformation = new RoundedCornersTransformation(view.getContext(), DimensionUtil.dipToPx(30), 0);
        loadGif(context,view,url,DEFAULT_RES,Target.SIZE_ORIGINAL,Target.SIZE_ORIGINAL, transformation);
    }

    public static void loadGif(Context context, ImageView view, String url, int defRes, int width, int height, Transformation transformation){
        RequestManager manager = getRequestManager(context);
        GifRequestBuilder<String> builder = manager
                .load(url)
                .asGif()
                .placeholder(defRes)
                .error(defRes)
                .override(width,height)
                .diskCacheStrategy(DiskCacheStrategy.SOURCE);
        if (transformation != null) {
            builder.transformFrame(transformation);
        }
        builder.into(view);
    }

    /**
     * 以Bitmap形式加载图片
     * 功能一：转换GIF为Bitmap
     * 功能二：配合SelectableRoundedImageView转换图片形状
     * @param context
     * @param view
     * @param url
     * @param defRes
     */
    public static void loadAsBitmap(Context context, ImageView view, String url, int defRes) {
        RequestManager manager = getRequestManager(context);
        BitmapRequestBuilder<String, Bitmap> builder = manager
                .load(url)
                .asBitmap()
                .placeholder(defRes)
                .error(defRes)
                .override(Target.SIZE_ORIGINAL,Target.SIZE_ORIGINAL)
                .diskCacheStrategy(DiskCacheStrategy.SOURCE);

        builder.into(view);
    }

    private static RequestManager getRequestManager(Context context){
        RequestManager manager;
        if (context instanceof BaseActivity){
            manager = ((BaseActivity) context).getImgRequestManager();
        }else {
            manager  = Glide.with(context);
        }
        if (manager.isPaused()){
            manager.resumeRequests();
        }
        return manager;
    }

    public static byte[] loadImageToByte(Context context, String url) {
        byte[] bytes = null;
        RequestManager manager = getRequestManager(context);
        try {
            Bitmap bitmap = manager.load(url).asBitmap().centerCrop().into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).get();
            bytes = bitmap2byte(bitmap);
        } catch (InterruptedException e) {
            bytes = null;
            e.printStackTrace();
        } catch (ExecutionException e) {
            bytes = null;
            e.printStackTrace();
        }
        return bytes;
    }

    public static byte[] loadImageToByteWithBaseActivity(Context context, String url) {
        byte[] bytes = null;
        RequestManager manager = Glide.with(context);
        try {
            Bitmap bitmap = manager.load(url).asBitmap().centerCrop().into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).get();
            bytes = bitmap2byte(bitmap);
        } catch (InterruptedException e) {
            bytes = null;
            e.printStackTrace();
        } catch (ExecutionException e) {
            bytes = null;
            e.printStackTrace();
        }
        return bytes;
    }

    /**
     * 清除内存缓存
     */
    public static void clearMemory(){
        Glide.get(MainApplication.getApp()).clearMemory();
    }

    /**
     * 清除图片磁盘缓存
     */
    public static void clearImageDiskCache(Context context) {
        try {
            if (Looper.myLooper() == Looper.getMainLooper()) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Glide.get(context).clearDiskCache();
                    }
                }).start();
            } else {
                Glide.get(context).clearDiskCache();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取Glide造成的缓存大小
     *
     * @return CacheSize
     */
    public static String getCacheSize(Context context) {
        try {
            return getFormatSize(getFolderSize(getDiskCacheFile(context, Config.IMG_CACHE_DIR)));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 格式化单位
     *
     * @param size size
     * @return size
     */
    public static String getFormatSize(double size) {

        double kiloByte = size / 1024;

        double megaByte = kiloByte / 1024;
        if (megaByte < 1) {
            BigDecimal result1 = new BigDecimal(Double.toString(kiloByte));
            return result1.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "KB";
        }

        double gigaByte = megaByte / 1024;
        if (gigaByte < 1) {
            BigDecimal result2 = new BigDecimal(Double.toString(megaByte));
            return result2.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "MB";
        }

        double teraBytes = gigaByte / 1024;
        if (teraBytes < 1) {
            BigDecimal result3 = new BigDecimal(Double.toString(gigaByte));
            return result3.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "GB";
        }
        BigDecimal result4 = new BigDecimal(teraBytes);

        return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "TB";
    }

    public static File getDiskCacheFile(Context context, String diskCacheName){
        File cacheDirectory = context.getExternalCacheDir();
        if (cacheDirectory == null) {
            return null;
        }
        if (diskCacheName != null) {
            return new File(cacheDirectory, diskCacheName);
        }
        return cacheDirectory;
    }


    /**
     * 获取指定文件夹内所有文件大小的和
     *
     * @param file file
     * @return size
     * @throws Exception
     */
    public static long getFolderSize(File file) throws Exception {
        long size = 0;
        try {
            File[] fileList = file.listFiles();
            for (File aFileList : fileList) {
                if (aFileList.isDirectory()) {
                    size = size + getFolderSize(aFileList);
                } else {
                    size = size + aFileList.length();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return size;
    }

    public static byte[] bitmap2byte (Bitmap bitmap) {
        /**
         * Bitmap.CompressFormat.JPEG 和 Bitmap.CompressFormat.PNG
         * JPEG 与 PNG 的是区别在于 JPEG是有损数据图像，PNG使用从LZ77派生的无损数据压缩算法。
         * 这里建议使用PNG格式保存
         * 100 表示的是质量为100%。当然，也可以改变成你所需要的百分比质量。
         * os 是定义的字节输出流
         * .compress() 方法是将Bitmap压缩成指定格式和质量的输出流
         */
        if (bitmap == null) return null;
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
        return os.toByteArray();
    }

    public static Bitmap byte2Bitmap(byte[] b) {
        return BitmapFactory.decodeByteArray(b, 0, b.length);
    }

    private static final int[] PIC_WIDTH = {240, 320, 480, 540, 640, 800, 854, 960};

    public static int getNeighbourWidth(float px, boolean upper) {
        int width;
        if (upper) {
            width = PIC_WIDTH[PIC_WIDTH.length - 1];
            for (int len = PIC_WIDTH.length, i = 0; i < len; i++) {
                if (px <= PIC_WIDTH[i]) {
                    width = PIC_WIDTH[i];
                    break;
                }
            }
        } else {
            width = PIC_WIDTH[0];
            for (int len = PIC_WIDTH.length, i = len - 1; i > -1; i--) {
                if (px >= PIC_WIDTH[i]) {
                    width = PIC_WIDTH[i];
                    break;
                }
            }
        }
        return width;
    }

    /**
     * 读取图片属性：旋转的角度
     * @param path 图片绝对路径
     * @return degree旋转的角度
     */
    public static int readPictureDegree(String path) {
        int degree  = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    /*
	 * 旋转图片
	 * @param angle
	 * @param bitmap
	 * @return Bitmap
	 */
    public static Bitmap rotatingImageView(int angle, Bitmap bitmap) {
        // 旋转图片 动作
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
        // 创建新的图片
        Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
                bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        return resizedBitmap;
    }

    public static void saveBitmap(Bitmap mBitmap, File file) {
        if (file == null) {
            return;
        }
        FileOutputStream fOut = null;
        try {
            fOut = new FileOutputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
        try {
            fOut.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            fOut.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
